home *** CD-ROM | disk | FTP | other *** search
- ;*********************************************
- ; * HERCULES GRAPHICS CARD UTILITY ROUTINES *
- ; * graph_mode(),text_mode(),plot(x,y) *
- ;*********************************************
- ;****************************************************************************
- ;* graph_mode() : puts the hercules graphics card into its graphics mode
- ;****************************************************************************
- ; ******** hercules port addresses ********
- INDEX_PORT equ 03b4H
- CTL_PORT equ 03b8H
- CONFIG_PORT equ 03BFH
-
- ; ******** hercules ctl codes **********
- SCRN_ON equ 8
- GRPH equ 2
- TEXT equ 20H
- FULL_MODE equ 03H
-
- DSEG
- gtable db 35H,2DH,2EH,07H
- db 5BH,02H,57H,57H
- db 02H,03H,00H,00H
-
- ttable db 61H,50H,52H,0FH
- db 19H,06H,19H,19H
- db 02H,0DH,0BH,0CH
-
- video_page_base_ dw 0,0B000H ;double-word addr= B000:0000H
-
- public cursor_x_,cursor_y_,grph_attrib_
- cursor_x_ dw 0
- cursor_y_ dw 0
- grph_attrib_ db 0
- CSEG
- setmd_:
- ; sets mode to graphics or TEXT
- ; depending on al
- ; si=parameter table
- ; cx=number of words to be cleared
- ; bx=blank value
- push ds
- push es
- push ax ;push mode
- push bx ;push blank value
- push cx ;push # of words to be cleared
-
- mov dx,CTL_PORT ;change mode but without SCRN_ON
- out dx,al
-
- mov ax,ds ;point es:si to parameter table
- mov es,ax
-
- mov dx,INDEX_PORT
- mov cx,12 ;12 parameters to be output
- xor ah,ah ;starting from reg 0
-
- parms: mov al,ah
- out dx,al
- inc dx
- lodsb
- out dx,al ; output data from table
- inc ah
- dec dx
- loop parms
-
- pop cx ;clear the buffer
- mov ax,0b000h
- cld ;setting up for string instruction here
-
- mov es,ax
- xor di,di
- pop ax
- rep stosw
-
- mov dx,CTL_PORT ;turn scrn on, point to page 0
- pop ax
- add al,SCRN_ON
- out dx,al
-
- pop es
- pop ds
- ret
-
- ;****************************************************************************
- ;* graph_mode() : puts the hercules graphics card into its graphics mode
- ;****************************************************************************
- CSEG
- public graph_mode_
- graph_mode_:
- push bp
- push es
- mov al,FULL_MODE
- mov dx,CONFIG_PORT
- out dx,al ;HGC FULL
- mov al,GRPH
- lea si,gtable
- mov bx,0
- mov cx,4000h
- call setmd_
- pop es
- pop bp
- ret
-
- ;****************************************************************************
- ;* TEXT_mode() : puts the hercules graphics card into TEXT mode
- ;****************************************************************************
-
- public TEXT_mode_
- TEXT_mode_:
- push bp
- push es
- mov al,TEXT
- lea si,ttable
- mov bx,720h
- mov cx,2000
- call setmd_
- pop es
- pop bp
- ret
-
- ;****************************************************************************
- ;* plot(x,y) lights the pixel located at coordinates x,y
- ;* Hercules graphics card version....
- ;****************************************************************************
- ;byte-addr = [2000H + (Ymod4)] + [90*INT(Y/4)] + INT(X/8)
- ;bit-offset = 7-(Xmod8)
- public plot_
- plot_: ;scrambles ax,bx,cx,dx,es
- push bp
- mov bp,sp
- mov ax,[bp+6] ;y in bx
- and ax,0003H ;(Ymod4) in bx
- mov bx,2000H
- mul bx ;(Ymod4)*2000H in ax
- mov bx,ax ;(Ymod4)*2000H in bx
-
- mov ax,[bp+6]
- shr ax,1
- shr ax,1 ;int(y/4) in ax
- mov cx,90 ;can't multiply by immediate
- mul cx ;int(y/4) * 90 in ax
- add bx,ax ;[int(y/4) * 90]+[(Ymod4)+2000H] in bx
-
- mov ax,[bp+4] ;x in ax
- shr ax,1
- shr ax,1
- shr ax,1 ;int(x/8) in bx
- add ax,bx ;whole byte offset address in ax
- les bx,video_page_base_ ;es:bx points to video base
- add bx,ax ;entire address in es:bx
- mov ax,[bp+4] ;X in ax
- and ax,0000000000000111B ;Xmod8 in ax
- mov cl,al ;Xmod8 becomes shift count
- mov al,10000000B ;start from the top
- shr al,cl ;bit pos is now in al, addr in es:bx
-
- or es:[bx],al ;this one does the deed!
-
- pop bp
- ret
-
- ;*****************************************
- ;* init_page_1() copies page 0 into page 1
- ;*****************************************
- public init_page_1_
- init_page_1_:
- push bp
- push es
- push si
- push di
- push ds
- mov ax,0B000H
- mov es,ax ;es and ds both point to video ram
- mov ds,ax ;no working variables... might have to move this one
- mov si,0 ;source is page 1
- mov di,8000H ;dest is page 2
- mov cx,8000H ;xfr 8000 bytes(one graphics page)
- cld ;going up...
- rep movsb ;do it to it!
- pop ds
- pop di
- pop si
- pop es
- pop bp
- ret
-
- ;*****************************************
- ;* init_page_0() copies page 1 into page 0
- ;*****************************************
- public init_page_0_
- init_page_0_:
- push bp
- push es
- push si
- push di
- push ds
- mov ax,0B000H
- mov es,ax ;es and ds both point to video ram
- mov ds,ax ;no working variables... might have to move this one
- mov si,8000H ;source is page 1
- mov di,0 ;dest is page 0
- mov cx,4000H ;xfr 8000 bytes(one graphics page)
- cld ;going up...
- rep movsw ;do it to it!
- pop ds
- pop di
- pop si
- pop es
- pop bp
- ret
-
- ;*******************************************************************
- ;* graphics_cls(page) clears the screen when it's in graphics mode *
- ;*******************************************************************
- ;1 process graphics_cls
- public graphics_cls_
- graphics_cls_:
-
- push bp
- mov bp,sp ;page# in [bp+4]
-
- ;2 if we need to clear page 0
- mov ax,[bp+4]
- or ax,ax
- jnz graphics_cls_1
-
- ;3 point at page 0
- mov di,0000H
-
- ;2 else(we need to clear page 1)
- jmp graphics_cls_2
- graphics_cls_1:
-
- ;3 point at page 1
- mov di,8000H
-
- ;2 endif(page 0 or 1?)
- graphics_cls_2:
-
- ;2 set up the rest of the block load
- mov ax,0B000H
- mov es,ax ;video base addr
- mov cx,8000H ;length of page
- mov ax,0
- cld ;load UP
- rep stosb
-
- ;2 zero out the graphics cursor
- mov ax,0
- mov cursor_x_,ax
- mov cursor_y_,ax
-
- ;1 endprocess graphics_cls
- pop bp
- ret
-
- ;/********************************************************/
- ; Hercules graphic text drawing routines
- ;/********************************************************/
- include "hercfont.a"
-
- y_table_: ;tells us the starting y offset for a char
- ;it has one entry for each of the 27 rows
- dw 0000H ;letter row 0
- dw 210EH ;letter row 1
- dw 421CH ;letter row 2
- dw 632AH ;letter row 3
- dw 0492H ;letter row 4
- dw 25A0H ;letter row 5
- dw 46AEH ;letter row 6
- dw 67BCH ;letter row 7
- dw 0924H ;letter row 8
- dw 2A32H ;letter row 9
- dw 4B40H ;letter row 10
- dw 6C4EH ;letter row 11
- dw 0DB6H ;letter row 12
- dw 2EC4H ;letter row 13
- dw 4FD2H ;letter row 14
- dw 70E0H ;letter row 15
- dw 1248H ;letter row 16
- dw 3356H ;letter row 17
- dw 5464H ;letter row 18
- dw 7572H ;letter row 19
- dw 16DAH ;letter row 20
- dw 37E8H ;letter row 21
- dw 58F6H ;letter row 22
- dw 7A04H ;letter row 23
- dw 1B6CH ;letter row 24
- dw 3C7AH ;letter row 25
-
-
- CSEG
- ;*******************************************
- ;* set plot_tty_cursor(x,y)
- ;*******************************************
- public set_plot_tty_cursor_
- set_plot_tty_cursor_:
- push bp
- mov bp,sp
- mov ax,[bp+4]
- mov cursor_x_,ax
- mov ax,[bp+6]
- mov cursor_y_,ax
- pop bp
- ret
-
- ;*******************************************
- ;1 process plot_char_tty(ascii_char)
- public plot_char_tty_
- plot_char_tty_:
- push bp
- mov bp,sp
-
- ;2 if this is not a control char
- mov al,[bp+4]
- and al,07FH
- cmp al,20H
- jc plot_char_tty_1
-
- ;3 output char at current cursor position
- mov al,[bp+4]
- push ax
- mov ax,cursor_y_
- push ax
- mov ax,cursor_x_
- push ax
- call plot_char_
- add sp,6
-
- ;3 increment cursor position
- call increment_cursor_
-
- ;2 else (ctl char)
- jmp plot_char_tty_2
- plot_char_tty_1:
-
- ;3 if the char is a <CR>
- mov al,[bp+4]
- cmp al,0Dh
- jnz plot_char_tty_3
-
- ;4 cursor_x_ = 0
- mov ax,0
- mov cursor_x_,ax
-
- ;3 else if the char is <LF>
- jmp plot_char_tty_4
- plot_char_tty_3:
- cmp al,0AH
- jnz plot_char_tty_4
-
- ;4 cursor_y_++
- mov ax,cursor_y_
- inc ax
- mov cursor_y_,ax
- cmp ax,26 ;line at bottom will roll over to
- jc plot_char_tty_5 ;top
- mov ax,0
- mov cursor_y_,ax
- plot_char_tty_5:
-
- ;3 endelseif
- plot_char_tty_4:
-
- ;2 endif(ctl char?)
- plot_char_tty_2:
-
- ;1 endprocess plot_char_tty
- pop bp
- ret
-
- ;************************************
- ;* plot_char(x,y,ascii_char)
- ;* x can be from 0 thru 89 [bp+4] = x,[bp+6]=y,[bp+8]=ascii_char
- ;* y can be from 0 thru 25
- ;************************************
- ;* sets global cursor_x and cursor_y to where it's own parameters
- ;we have defined font patterns for ascii 20H thru 5AH
- ;1 process plot_char ;destroys contents of bx,si,ax,es
- public plot_char_
- plot_char_:
- push bp
- mov bp,sp
-
- ;2 convert the ascii char to a table pointer
- mov al,[bp+8]
- push ax
- call convert_ascii_
- add sp,2
- mov [bp+8],ax ;table ptr in [bp+8]
-
- ;2 point to the beginning of the char in video ram
- les bx,video_page_base_ ;es:bx point to video card base
- mov bx,[bp+6] ;y in bx
- add bx,bx ;two bytes per table entry
- mov ax,y_table_[bx] ;address in ax
- add ax,[bp+4] ;add in x
- mov bx,ax ;es:bx now point to video board char position
-
- mov si,[bp+8] ;ds:si points to table
- mov al,[si] ;first byte in al
- xor al,grph_attrib_ ;reverse video?
- mov es:[bx],al ;out to video
-
- ;2 repeat
- mov cx,9
- plot_char_1:
-
- ;3 increment table pointer
- inc si
-
- ;3 increment video ram pointer
- add bx,2000H ;point to next bank
- cmp bx,8000H ;do we roll over
-
- jc plot_char_2 ;pop over this next if 8000H bigger
- add bx,5AH
- and bx,1FFFH ;and referance back down to 1st bank
- plot_char_2:
-
- ;3 move char pattern out to video ram
- mov al,[si]
- xor al,grph_attrib_ ;reverse video if grph_attrib=ff
- mov es:[bx],al
-
- ;2 9 times
- loop plot_char_1
-
- ;1 endprocess plot_char
- pop bp
- ret
-
- ;1 process convert_ascii
- public convert_ascii_
- convert_ascii_:
- push bp
- mov bp,sp ;input parameter = [bp+4]
-
- ;2 make input into 7-bit ascii
- mov al,[bp+4]
- and al,07FH
- mov [bp+4],al
-
- ;2 if input > bottom-ot-ascii-table -1
- cmp al,17H
- jc convert_ascii_1
-
- ;3 if input < end of ascii table + 1
- mov al,[bp+4]
- sub al,7BH
- jnc convert_ascii_3
-
- ;4 just leave it unmolested
-
- ;3 else (input > 5BH)
- jmp convert_ascii_4
- convert_ascii_3:
-
- ;4 return space
- mov byte [bp+4],20H
-
- ;3 endif(input < 5bH?)
- convert_ascii_4:
-
- ;2 else (input not greater than 1FH)
- jmp convert_ascii_2
- convert_ascii_1:
-
- ;2 return space
- mov byte [bp+4],20H
-
- ;2 endif
- convert_ascii_2:
-
- ;2 get the output parameter
- mov ax,[bp+4] ;index into table
- sub ax,18H ;- offset(18H is first table entry)
- mov bx,10 ;times bytes/entry
- mul bx ;answer still fits in ax
- add ax,offset ascii_table_
-
- ;1 endprocess convert_ascii
- pop bp
- ret
-
- ;*******************************************
- ;1 process plot_string(string)
- public plot_string_
- plot_string_:
- push bp
- mov bp,sp
-
- ;2 get parameter
- mov bx,[bp+4]
-
- ;2 get first char
- mov al,[bx]
-
- ;2 repeat
- plot_string_1:
-
- ;3 plot_char_tty(char)
- push bx
- push ax
- call plot_char_tty_
- add sp,2
- pop bx
-
- ;3 get next char
- inc bx
- mov al,[bx]
-
- ;2 until character=0
- or al,al
- jnz plot_string_1
-
- ;1 endprocess plot_string
- pop bp
- ret
-
- ;*******************************************
- ;1 process increment_cursor
- public increment_cursor_
- increment_cursor_:
- push bp
-
- ;2 increment cursor_x_ position
- mov ax,cursor_x_
- inc ax ;cursor_x_+1 in ax
- mov cursor_x_,ax
-
- ;2 if cursor_x_ got to 80
- cmp ax,80
- jc increment_cursor_1
-
- ;3 cursor_x_ = 0
- mov ax,0
- mov cursor_x_,ax
-
- ;3 cursor_y_++
- mov ax,cursor_y_
- inc ax
- mov cursor_y_,ax
-
- ;3 if cursor_y_ = 26
- cmp ax,26
- jnz increment_cursor_2
-
- ;4 cursor_y_ = 0
- mov ax,0
- mov cursor_y_,ax
-
- ;3 endif(cursor_y_= 26?)
- increment_cursor_2:
-
- ;2 endif(cursor_y_= 80?)
- increment_cursor_1:
-
- ;1 endprocess increment_cursor_
- pop bp
- ret
-
-